Post

Replies

Boosts

Views

Activity

Reply to Application running a daemon, what about uninstalling?
Hi Quinn, Well, maybe yes, my "daemon", allow me :) is started by launchd, the plist is correctly set to /library/launchdaemons, system restart and it will start with the OS. For close I will launchctl load or unload to stop. And yes, Packages is a 3rd party app to create installer package (free). That said all seems to work but I am not sure on how it would work when uninstalling. Today I will prepare the installer and give a try but I dont see a way to remove it, unless MacOS is very clever and somehow knows that once we move the app to trash it will also move the daeamon... Thanks
Jan ’24
Reply to JSONEncoder issue?
Which type of func is it ? If async, it could be a concurrency issue. Yes, it is async and after reading some of your questions I refactored some parts and seems to be working now. Anyway it's one of the expected weird behaviors when not dealing well with threads. Thank you guys!
Jun ’23
Reply to JSONEncoder issue?
I will paste the full code, this is from Playground, now running on playground it won't separate the array, so I guess that can be related to the way I am doing in the real code, there it is called inside another function, so I think that I will enclosure it a thread and see what happens. The code below works fine. Also, I know I can simply use wifiList.removeAll() instead of wifiList.removeAll(keepingCapacity: false), but as someone with little knowledgement in Swift I use that way to force me to learn about other options. import Foundation import CoreWLAN class Discovery { var currentInterface: CWInterface var interfacesNames: [String] = [] var networks: Set<CWNetwork> = [] // Failable init using default interface init?() { if let defaultInterface = CWWiFiClient.shared().interface(), let name = defaultInterface.interfaceName { self.currentInterface = defaultInterface self.interfacesNames.append(name) self.findNetworks() } else { return nil } } init(interfaceWithName name: String) { self.currentInterface = CWWiFiClient().interface(withName: name)! self.interfacesNames.append(name) self.findNetworks() } // Fetch detectable WIFI networks func findNetworks() { do { self.networks = try currentInterface.scanForNetworks(withSSID: nil) } catch let error as NSError { print("Error: \(error.localizedDescription)") } } } struct Wifi: Codable { var SSID: String var bSSID: String var Channel: Int var Band: String var Width: String var noise: Int var rssi: Int var qualitySNR: Int var isConnected: Bool init() { SSID = "" bSSID = "00:00:00:00:00:00" Channel = 0 Band = "" Width = "" rssi = 0 noise = 0 qualitySNR = 0 isConnected = false } } var wifiList: [Wifi] = [] func getWifiNetworks() { var connectedNetwork = "" wifiList.removeAll(keepingCapacity: false) if let discovery = Discovery() { var wifi: Wifi let connectedNetwork = CWWiFiClient.shared().interface()!.ssid()! for network in discovery.networks { wifi = Wifi.init() wifi.SSID = network.ssid?.description ?? "" wifi.isConnected = wifi.SSID == connectedNetwork wifi.bSSID = network.bssid?.description ?? "00:00:00:00:00:00" wifi.Channel = network.wlanChannel?.channelNumber ?? 0 wifi.rssi = network.rssiValue wifi.noise = network.noiseMeasurement wifi.qualitySNR = wifi.rssi - wifi.noise switch network.wlanChannel?.channelBand { case .bandUnknown: wifi.Band = "Unknown" case .band2GHz: wifi.Band = "2Ghz" case .band5GHz: wifi.Band = "5Ghz" case .band6GHz: wifi.Band = "6Ghz" case .none: wifi.Band = "Unknown" case .some(_): wifi.Band = "Unknown" } switch network.wlanChannel?.channelWidth { case .width160MHz: wifi.Width = "160MHz" case .none: wifi.Width = "none" case .some(.widthUnknown): wifi.Width = "Unknown" case .some(.width20MHz): wifi.Width = "20MHz" case .some(.width40MHz): wifi.Width = "40MHz" case .some(.width80MHz): wifi.Width = "80MHz" case .some(_): wifi.Width = "Unknown" } wifi.rssi = network.rssiValue wifiList.insert(wifi, at: 0) } } } func convertWifiListToString() -> String { let encoder = JSONEncoder() let data = try! encoder.encode(wifiList) return String(data: data, encoding: .utf8)! } getWifiNetworks() let wifiListJson = convertWifiListToString() print(wifiListJson)
Jun ’23
Reply to JSONEncoder issue?
Ok, this is my struct and the list, the real one: struct Wifi: Codable { var SSID: String var bSSID: String var Channel: Int var Band: String var Width: String var noise: Int var rssi: Int var qualitySNR: Int var isConnected: Bool init() { SSID = "" bSSID = "00:00:00:00:00:00" Channel = 0 Band = "" Width = "" rssi = 0 noise = 0 qualitySNR = 0 isConnected = false } } var wifiList: [Wifi] = [] Here is how I do populate it: wifiList.removeAll(keepingCapacity: false) //... get all stuff from the network and insert into the list // wifi is declared as wifi = Wifi.init() wifiList.insert(wifi, at: 0) After the list if completed I convert it string, as I showed before: func convertToJSONString() -> String { let encoder = JSONEncoder() let data = try! encoder.encode(wifiList) return String(data: data, encoding: .utf8)! } What I get: [{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-77,"SSID":"CLARO_2GA37FE4","Channel":6,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-153},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-74,"SSID":"2.4G DEMOLIDOR HELMAR LUAN","Channel":8,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-150},{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-88,"SSID":"TP-LINK_9562_5G","Channel":157,"isConnected":false,"Width":"80MHz","noise":76,"qualitySNR":-164},{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-77,"SSID":"AP 71 A-5G","Channel":52,"isConnected":false,"Width":"80MHz","noise":76,"qualitySNR":-153},{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-48,"SSID":"XIMA","Channel":157,"isConnected":true,"Width":"80MHz","noise":76,"qualitySNR":-124},{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-83,"SSID":"5.G DEMOLIDOR HELMAR LUAN","Channel":48,"isConnected":false,"Width":"80MHz","noise":76,"qualitySNR":-159},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-61,"SSID":"LIMA_2G","Channel":10,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-137},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-76,"SSID":"Net-Virtua-9095-2.4G","Channel":1,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-152},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-84,"SSID":"#NET-CLARO-WIFI","Channel":1,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-160},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-91,"SSID":"Renato.2G","Channel":11,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-167},{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-78,"SSID":"AP 71 A","Channel":52,"isConnected":false,"Width":"80MHz","noise":76,"qualitySNR":-154},{"bSSID":"00:00:00:00:00:00","Band":"2Ghz","rssi":-85,"SSID":"Vila Mariana","Channel":1,"isConnected":false,"Width":"40MHz","noise":76,"qualitySNR":-161}] [{"bSSID":"00:00:00:00:00:00","Band":"5Ghz","rssi":-52,"SSID":"XIMA","Channel":157,"isConnected":false,"Width":"80MHz","noise":80,"qualitySNR":-132}] In this example, the last item shouldn't be "out" of the array. The result shows like 2 arrays and I expect to have only one.
Jun ’23
Reply to How to show permissions for Location Services at Privacy & Security menu?
Adding something else to this thread. Here a sample code that I use in my original code (not exactly this way, but the main part is quite close) I started a new Command Line Tool with Xcode 14.2, i notice that there's no more config.plist so I take from my app to ensure that NSLocationAlwaysUsageDescription, NSLocationUsageDescription and NSLocationWhenInUseUsageDescription are there - config.plist attached here too. No luck with Ventura so far. config.plist.txt import Foundation import CoreLocation struct TCoordinates {   var latitude: Double = 0   var longitude: Double = 0   var altitude: Double = 0   var course: Double = 0   var precision: Double = 0 } let locationManager = CLLocationManager() var coordinates: TCoordinates coordinates = TCoordinates.init() func getCoordinates(locationManager: CLLocationManager) -> TCoordinates {   var ret = TCoordinates.init()   ret.latitude = locationManager.location?.coordinate.latitude ?? 0   ret.longitude = locationManager.location?.coordinate.longitude ?? 0   ret.altitude = locationManager.location?.altitude ?? 0   ret.course = locationManager.location?.course ?? 0   ret.precision = locationManager.location?.horizontalAccuracy ?? 0   return ret } private func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {   switch status {   case .notDetermined:     // If status has not yet been determied, ask for authorization     manager.requestWhenInUseAuthorization()     break   case .authorizedWhenInUse:     // If authorized when in use     manager.startUpdatingLocation()     break   case .authorizedAlways:     // If always authorized     manager.startUpdatingLocation()     break   case .restricted:     // If restricted by e.g. parental controls. User can't enable Location Services     break   case .denied:     // If user denied your app access to Location Services, but can grant access from Settings.app     break   default:     break   } } func getGeoLocation() {   coordinates = getCoordinates(locationManager: locationManager)       if CLLocationManager.locationServicesEnabled() {           let authorizationStatus: CLAuthorizationStatus           if #available(iOS 14, *) {       authorizationStatus = locationManager.authorizationStatus     } else {       authorizationStatus = CLLocationManager.authorizationStatus()     }           switch authorizationStatus {     case .restricted, .notDetermined:       locationManager.requestAlwaysAuthorization()       print("Restricted")       exit(0)     case .denied:       print("Denied")     case .authorizedAlways, .authorizedWhenInUse:       print("Authorized")     case .authorized:       print("Authorized")     @unknown default:       print("Unavailable")     }   } } /* -------- */ locationManager.startUpdatingLocation()     getGeoLocation() autoreleasepool {   RunLoop.main.run() }
Dec ’22
Reply to Issue with string
Hi Claude, sorry and thanks for you patience!! I FIXED the issue! Could you show how you get data ? The data is typed in the user interface configuration form. I made a kind of helper to use the SQLite, so it can read and update tables and there was one of the issues. With this helper I can handle the database and table as easy as: var db: OpaquePointer? var sqlQuery: sqliteQuery var sqlText: OpaquePointer? = nil let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false) .appendingPathComponent("/mydatabase.sqlite") let sqlText = "INSERT INTO TABLE (user, password, status, date) VALUES (:user, :password, :status, :date);" if sqliteOpenDatabase(DatabaseURL: fileURL, Database: &db) == SQLITE_OK { sqlQuery = sqliteQuery(Database: &db, Statement: &sqlText, Query: queryString) sqlQuery.ParamByName(Param: "user", ValueType: .string, Value: "Username" ) sqlQuery.ParamByName(Param: "password", ValueType: .string, Value: "123456" ) sqlQuery.ParamByName(Param: "status", ValueType: .string, Value: "valid" ) sqlQuery.ParamByName(Param: "date", ValueType: .date , Value: Date() ) sqlQuery.ExecSQL() print(sqlQuery.ParamByName(Param: "user")) } Where do data come from ? The data comes from a SQLite table What is exactly in value ? Is it an optional ? Think about saving a email field into a table. You should open the table and read something like "myname@site. com" (this forum dont allow type emails, so theres no space here, its an example) but once you read it (any program including and besides yourself) you would get as email a weird string as I was tolding: "Optional("myname@site. com")" and that messed up with everything. To fix that I had to dig into the code and change all old Optional string convertions, even things like String(cString: value) are depreciated . Things such: return anyData == nil ? "" : anyData as! String I had to change to return String(describing: anyData) Also I had to perform a lot of changes in the ancient code. Again thanks for the support and patience!
Dec ’22
Reply to Issue with string
I figure out the issue but still unable to fix it. Firstly, I made it stop working with me by replicating all the steps the user do. Once the data is read from the SQLite table from a field type string (text typed in SQLite) using sql_column_text() function the result itself contains literal text of "Optional"and will break everything. real code when I am attempting to fix, reading user department: let stringValue = String(cString: sqlite3_column_text(Statement, index)) // attempt This will show in the debugger as "Optional(\"Dev team\")" and the UI where the user changes the information, also shows exactly that way! All of this trouble after updating to XCode 5 (original was done with version 4). I opened the database using a 3rd party software and these characters are there! Here how I read the data: struct ColumnValue { var Column: String var Value: Any? // Need to be any because will support int, float, string at least.. using Any or Any makes no difference } var ResultSet: [ColumnValue] var columnValue: ColumnValue // ... after open database, now scroll the table // simplified loop while true { for index in 0..<sqlite3_column_count(Statement) { let column = String(cString: sqlite3_column_origin_name(Statement, index)!) let type = sqlite3_column_type(Statement, index) switch type { // if column is type of string (text) case SQLITE_TEXT, SQLITE3_TEXT: let stringValue = String(cString: sqlite3_column_text(Statement, index)!) columnValue = ColumnValue(Column: column, Value: stringValue) default: columnValue = ColumnValue(Column: column, Value: nilAny) } ResultSet.insert(columnValue, at: 0) self.RowCount += 1 if sqlite3_step(Statement) == SQLITE_DONE { break } } } All the issue is because stringValue is storing literal characters of the optional type. The information read should be a plain string like "Dev team", as I worked until now, and not that weird string "Optional(\"Dev team\")"
Dec ’22
Reply to Issue with string
Hi man! Well config is a global var, after this lines bellow I initiate var config = Config.init() And Yes, loadConfiguration is populating the config, exatly like: // after read the host field in the config table this is what I do: config.endpoint = (data.Value as! String).trimmingCharacters(in: .whitespacesAndNewlines) I also tried: config.endpoint = String((data.Value as! String).trimmingCharacters(in: .whitespacesAndNewlines)) The data contains the value fetched from the table. Because of data.Value as! String I guess that the original string is an optional. How could I "fix" that? Or why would the program fail that way?
Dec ’22
Reply to Issue with string
Here the real code, part of it: // part of the struct struct Config { var endpoint: String var endpoint_scheme: String var endpoint_path: String var endpoint_port: Int32   init() {     endpoint = ""     endpoint_path = ""     endpoint_port = 0     endpoint_scheme = ""   } } // part of the function that would sent data func submitJson(jsonData: String, scheme: String, host: String, path: String, port: Int32, completion:((Error?) -> Void)?) -> Bool { var urlComponents = URLComponents() urlComponents.scheme = scheme urlComponents.host = host urlComponents.path = path urlComponents.port = Int(port) print(host) // this is just when I was trying to figure out what "invalid ' characters the app was complaining guard let url = urlComponents.url else { displayInfo(info: "URL configuration is invalid") return false } // the rest of the code goes below, when it will fail to post the data due that invalid characters } // other place I should use: var config = Config.init() loadConfiguration() // somewhere it reads the SQLite // and when need I will send some stuff based on the configuration result = submitJson(jsonData: jsonDataStr, scheme: config.endpoint_scheme, host: config.endpoint, path: config.endpoint_path, port: config.endpoint_port) Again, this works with my computer. That print won't display "Optional("anyendpoint.com")" but as an example in my computer it prints simple plain text "anyendpoint.com" Thanks again
Dec ’22
Reply to Issue with string
Actually I think I can add this, which is how the var passed to the function get its value: myStruct.theString = (data.Value as! String).trimmingCharacters(in: .whitespacesAndNewlines) The data.Value here is a string I read from a SQLite table. So when running myStruct.theString = (data.Value as! String).trimmingCharacters(in: .whitespacesAndNewlines) func(param: myStruct.theString) Results output as: Optional("Test") This gives an error of invalid characters at my client computer, but running the same code with my computer: Test There isn't mention to "Optional" and runs flawlessly
Dec ’22
Reply to Issue with string
Hi again This is an app, compiled and running on the terminal. About the use of the function its just like test(param: str). My real program is passing a struct property to the function, like test(param: myStruct.theString) the struct defines "theString" as String type. I really don't have a lot to show.
Dec ’22